//
//  GJNetWork.m
//  xmgjAppFront
//
//  Created by Zeki on 2020/7/8.
//  Copyright © 2020 guojutech. All rights reserved.
//

#import "GJNetWork.h"


static const NSTimeInterval kTimeoutInterval = 30.f; // 请求超时时间
static const NSInteger kMaxRetryCount = 1; // 请求失败重试的最大次数

/**
 *  404错误
 */
static NSString* const kNotConnectToServer = @"Could not connect to the server.";
static NSString* const kNotConnectToServerZH = @"网络连接异常，请稍后再试";
/**
 *  500错误
 */
static NSString* const kServerError = @"Request failed: internal server error (500)";
static NSString* const kServerErrorZH = @"服务器异常，请稍后再试";


@implementation GJNetWork
+ (instancetype)sharedInstance {
    static GJNetWork *network = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        network = [GJNetWork manager];
        network.requestSerializer = [AFJSONRequestSerializer serializer];
        network.requestSerializer.HTTPShouldHandleCookies = NO;
        network.responseSerializer = [AFJSONResponseSerializer serializer];
        network.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
                                                             @"text/html", nil];
        network.securityPolicy = [GJNetWork securityPolicy];
        [network startMonitoringNetworkType];
        
        network.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
    });
    network.requestSerializer.timeoutInterval = kTimeoutInterval; // 每次调用默认30s，可做修改
    return network;
}

+ (AFSecurityPolicy *)securityPolicy {
  AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
  securityPolicy.validatesDomainName = NO;
  securityPolicy.allowInvalidCertificates = YES;
  return securityPolicy;
}
- (void)startMonitoringNetworkType {
  AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
  @weakify(self);
  [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    @strongify(self);
    switch (status) {
      case AFNetworkReachabilityStatusUnknown:
        self.networkType = @"Unknown";
        break;
      case AFNetworkReachabilityStatusNotReachable:
        self.networkType = @"NotReachable";
        break;
      case AFNetworkReachabilityStatusReachableViaWWAN:
        self.networkType = @"4G";
        break;
      case AFNetworkReachabilityStatusReachableViaWiFi:
        self.networkType = @"WIFI";
        break;
    }
  }];
  [manager startMonitoring];
}


- (NSURLSessionDataTask *)postWithURL:(NSString *)url params:(NSDictionary *)params success:(Success)success failure:(Failure)failure{
  if (!params) {
    params = @{};
  }
  
  return [self POST:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    GJLog(@"POST请求地址：%@", url);
    GJLog(@"POST请求参数：%@", [params jsonPrettyStringEncoded]);
    GJLog(@"POST响应结果：%@", [[responseObject jsonPrettyStringEncoded] stringByReplacingOccurrencesOfString:@"\\" withString:@""]);
    GJResponse *response = [GJResponse mj_objectWithKeyValues:responseObject];
    if (response.isSuccess) {
      if (success) {
        success(response);
      }
    }else{
      failure(response.msg ? response.msg : @"访问数据失败");
    }
  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    GJLog(@"POST请求地址：%@", url);
    GJLog(@"POST请求参数：%@", [params jsonPrettyStringEncoded]);
    GJLog(@"错误信息：%@", error);
    if (failure) {
      if ([error.localizedDescription containsString:kNotConnectToServer]) {
        failure(kNotConnectToServerZH);
      } else if ([error.localizedDescription containsString:kServerError]) {
        failure(kServerErrorZH);
      } else {
        failure(kNotConnectToServerZH);
      }
    }
  }];
}
- (NSURLSessionDataTask *)getWithURL:(NSString *)url params:(NSDictionary *)params success:(Success)success failure:(Failure)failure{
  if (!params) {
    params = @{};
  }
  return [self GET:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject)  {
    GJLog(@"get请求地址：%@", url);
    GJLog(@"get请求参数：%@", [params jsonPrettyStringEncoded]);
    GJLog(@"get响应结果：%@", [[responseObject jsonPrettyStringEncoded] stringByReplacingOccurrencesOfString:@"\\" withString:@""]);
    GJResponse *response = [GJResponse mj_objectWithKeyValues:responseObject];
    if (response.isSuccess) {
      if (success) {
        success(response);
      }
    }else{
      failure(response.msg ? response.msg : @"访问数据失败");
    }
    
  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    GJLog(@"get请求地址：%@", url);
    GJLog(@"get请求参数：%@", [params jsonPrettyStringEncoded]);
    GJLog(@"错误信息：%@", error);
    if (failure) {
      if ([error.localizedDescription containsString:kNotConnectToServer]) {
        failure(kNotConnectToServerZH);
      } else if ([error.localizedDescription containsString:kServerError]) {
        failure(kServerErrorZH);
      } else {
        failure(kNotConnectToServerZH);
      }
    }
  }];
}

/**
 *  自定义POST方法
 *
 *  @param retryCount 重试请求次数
 */
- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    retryCount:(NSInteger)retryCount
                    parameters:(id)parameters
                      progress:(void (^)(NSProgress *))uploadProgress
                       success:(void (^)(NSURLSessionDataTask *, id))success
                       failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
  if (retryCount <= 0) {
    if (failure) {
      NSError *error = [NSError errorWithDomain:kNotConnectToServer code:404 userInfo:nil];
      failure(nil, error);
    }
    return nil;
  } else {
    NSInteger currentRetryCount = kMaxRetryCount - retryCount;
    if (currentRetryCount > 0) {
      GJLog(@"%@--------当前retryCount： %@", URLString, @(currentRetryCount));
    }
    __weak __typeof(&*self) weakSelf = self;
    return [self POST:URLString
           parameters:parameters headers:nil
             progress:uploadProgress
              success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
      if (success) {
        success(task, responseObject);
      }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
      if (retryCount == 1) {
        GJLog(@"请求地址：%@", URLString);
        GJLog(@"错误信息：%@", error);
      }
      [weakSelf POST:URLString
          retryCount:(retryCount - 1)
          parameters:parameters
            progress:uploadProgress
             success:success
             failure:failure];
    }];
  }
}
@end
